立即函式 IIFE
的全名為 Immediately Invoked Function Expression,顧名思義就是立刻執行的函式。
IIFE
最大的特色就是能避免變數汙染到全域(global scope),因此在框架上常看到這種用法,能避免框架與使用者定義的變數衝突。
我們可以使用具名 / 匿名函式、或函式表示式(Functions Expressions),用 ()
將函式包起來,最後再增加一個 ()
,如下:
(function () {
console.log("立即函式!")
})();
(function fn() {
console.log("立即函式!!");
})();
const fn2 = (function () {
console.log("立即函式!!!")
})();
為什麼用 ()
將 function 包起來?因為在包住表達式時會回傳結果。當第一個字是 (
的時候,JavaScript 就知道這是表達式。
// 陳述式,必須有名字
function sayHi(){
console.log("Hi");
};
除了開頭的用法外,也可以使用匿名函式:
(function(){
console.log("Hi")
}());
在包起來後我們還要在結尾加上 ()
呼叫,不然只是存在記憶體而已。
既然後面的 () 表示呼叫函式,那我們就可以在裡面放入要傳遞的參數
(function(name){
console.log(name);
})("Peter") // 放參數
const fn = function(name){
console.log(`Hi ${name}`);
}("Peter");
一般的函式本來就有限制作用域,不過立即函式是「整個函式」都限制住,意思就是即使這個函式是具名函式,還是沒辦法在其他地方呼叫。
下面我們嘗試呼叫這個具名的匿名函式,發現程式噴給我們 is not defined
。
(function sayHi(){
console.log("Hi")
}());
sayHi()
// Uncaught ReferenceError: sayHi is not defined
這就是文章最開始提到:立即函式能避免全域被汙染。
當然我們有可能會有修改全域變數的需求,這時可以將 window 當成參數傳入立即函式:
var name = "Peter";
(function (gloabl) {
console.log(gloabl.name) // Peter
})(window);